package net.chenlin.dp.ids.client.filter;

import net.chenlin.dp.ids.client.config.PassportClientConfig;
import net.chenlin.dp.ids.client.manager.AuthCheckManager;
import net.chenlin.dp.ids.common.constant.GlobalErrorEnum;
import net.chenlin.dp.ids.common.constant.IdsConst;
import net.chenlin.dp.ids.common.entity.SessionData;
import net.chenlin.dp.ids.common.util.CommonUtil;
import net.chenlin.dp.ids.common.util.CookieUtil;
import net.chenlin.dp.ids.common.util.JsonUtil;
import net.chenlin.dp.ids.common.util.WebUtil;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * ids web过滤器
 * @author zcl<yczclcn@163.com>
 */
public class PassportWebAuthFilter implements Filter {

    private FilterConfig filterConfig;

    private PassportClientConfig clientConfig;

    private AuthCheckManager authCheckManager;

    public PassportWebAuthFilter(PassportClientConfig clientConfig, AuthCheckManager authCheckManager) {
        this.clientConfig = clientConfig;
        this.authCheckManager = authCheckManager;
    }

    @Override
    public void init(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    /**
     * 过滤器链
     * @param request
     * @param response
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest servletRequest = (HttpServletRequest) request;
        HttpServletResponse servletResponse = (HttpServletResponse) response;
        String servletPath = servletRequest.getServletPath();
        // 匿名请求
        if (clientConfig.isAnonUrl(servletPath)) {
            chain.doFilter(request, response);
            return;
        }
        // 登出请求
        if (IdsConst.LOGOUT_URL.equals(servletPath)) {
            // 跳转登出地址
            String logoutUrl = WebUtil.requestAppendParam(clientConfig.getServLogoutUrl(),
                    new String[]{IdsConst.REDIRECT_KEY}, new Object[]{clientConfig.getServerName()});
            servletResponse.sendRedirect(logoutUrl);
            return;
        }
        SessionData sessionData = authCheckManager.checkWebSession(servletRequest);
        if (sessionData == null) {
            // 删除cookie
            CookieUtil.remove(servletRequest, servletResponse, clientConfig.getAuthIdCookieName(),
                    clientConfig.getCookieDomain());
            // 从请求中获取sessionId
            String sessionId = servletRequest.getParameter(IdsConst.SESSION_PARAM_KEY);
            if (CommonUtil.strIsNotEmpty(sessionId)) {
                sessionData = authCheckManager.checkClientSession(sessionId, IdsConst.LOGIN_TYPE_WEB);
                // 将sessionId写入cookie
                if (sessionData != null) {
                    CookieUtil.set(servletResponse, clientConfig.getAuthIdCookieName(), sessionId,
                            clientConfig.getCookieDomain(), sessionData.getRememberMe());
                }
            }
        }

        // 登录失败
        if (sessionData == null) {
            // ajax请求
            if (WebUtil.isAjax(servletRequest)) {
                String result = JsonUtil.toStr(GlobalErrorEnum.NOT_LOGIN.getResult());
                WebUtil.write(servletResponse, result);
                return;
            }
            // 重定向登录地址
            String requestUrl = servletRequest.getRequestURL().toString();
            servletResponse.sendRedirect(clientConfig.getServLoginUrl(requestUrl));
            return;
        }
        // 登录成功
        request.setAttribute(IdsConst.SESSION_KEY, sessionData);
        // 非记住密码类型session，更新session过期时间
        if (!sessionData.getRememberMe()) {
            authCheckManager.refreshWebSession(servletRequest);
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        this.filterConfig = null;
    }

}
